package com.wzdigit.wms.wms.service.core.inventory;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wzdigit.framework.Shift;
import com.wzdigit.mes.basic.api.BasicDataItemDetailApi;
import com.wzdigit.mes.basic.dto.DataItemDetailDTO;
import com.wzdigit.wms.basic.client.Pager;
import com.wzdigit.wms.basic.client.PagerInfo;
import com.wzdigit.wms.basic.client.request.basic.ImportGoodsTempRequest;
import com.wzdigit.wms.basic.client.request.basic.SearchGoodsTempRequest;
import com.wzdigit.wms.basic.client.response.basic.GoodsTempResponse;
import com.wzdigit.wms.basic.client.response.basic.ImportGoodsTempErrorResponse;
import com.wzdigit.wms.basic.client.response.basic.ImportGoodsTempResponse;
import com.wzdigit.wms.basic.enums.*;
import com.wzdigit.wms.basic.enums.workdivision.WorkDivisionIsEnabledEnum;
import com.wzdigit.wms.basic.mapper.core.basic.SkuMapper;
import com.wzdigit.wms.basic.mapper.core.inventory.GoodsTempMapper;
import com.wzdigit.wms.common.utils.HttpExcel;
import com.wzdigit.wms.basic.util.HttpSessionUtil;
import com.wzdigit.wms.common.utils.ValidatorUtil;
import com.wzdigit.wms.common.entity.StatusCode;
import net.dreamlu.mica.core.utils.BeanUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 货品临时清单Service
 * Created by zyf on 2021/5/17 12:41
 */
@Service
public class GoodsTempService {

    @Autowired
    private GoodsTempMapper goodsTempMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Reference(version = "${dubbo.consumers.basic.data.item.detail.api:1.0.0}", check = false, timeout = 300000)
    private BasicDataItemDetailApi dataItemDetailApi;

    @Value(value = "${default_owner.code}")
    private String DEFAULT_OWNER;

    @Value(value = "${default_owner.name}")
    private String DEFAULT_OWNER_NAME;

    private String[] soTypes={"易损件订单","整机订单","样机订单","散件订单"};

    private String[] sellFlags={"外销OEM","外销品牌","内销"};

    private Date stringChangeDate(String value) {
        Date date = null;
        try {
            if (value.length() <= 5) {
                date = HSSFDateUtil.getJavaDate(Double.parseDouble(value));
                return date;
            }
            if (value.trim().contains("/")) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
                date = simpleDateFormat.parse(value);
            } else if (value.trim().contains("-")) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                date = simpleDateFormat.parse(value);
            } else if (value.trim().contains(".")) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd");
                date = simpleDateFormat.parse(value);
            } else if (value.trim().contains("年") && value.trim().contains("月") && value.trim().contains("日")) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
                date = simpleDateFormat.parse(value);
            } else if (value.trim().contains("年") && value.trim().contains("月")) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd");
                date = simpleDateFormat.parse(value);
            } else {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
                date = simpleDateFormat.parse(value);
            }
        } catch (Exception ex) {
            return date;
        }
        return date;
    }

    //校验字段是否为空
    private String  checkNotNull(ImportGoodsTempRequest dto){
        StringBuilder errorDec = new StringBuilder("【第");
        errorDec.append(dto.getRow()).append("行】");
        if (dto.getGoodsSn()==null){
            errorDec.append("整机SN不能为空,");
        }
        if (dto.getSkuIdString()==null){
            errorDec.append("整机物料代码不能为空,");
        }
        if (dto.getFactory()==null){
            errorDec.append("工厂代码不能为空,");
        }
        if (dto.getPoNo()==null){
            errorDec.append("内需单号不能为空,");
        }
        if (dto.getSoNo()==null){
            errorDec.append("销售订单号不能为空,");
        }
        if (dto.getSoItem()==null){
            errorDec.append("销售订单行不能为空,");
        }

        return errorDec.deleteCharAt(errorDec.length()-1).toString();


    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public ImportGoodsTempResponse importGoodsTemp(
            MultipartFile file,
            HttpServletRequest servletRequest,
            HttpServletResponse servletResponse) throws Exception {
        String loginName = HttpSessionUtil.getLoginName(servletRequest);
        List<ImportGoodsTempRequest> excel = null;
        try {
            InputStream inputStream = file.getInputStream();
            String[] properties = { "goodsSn", "skuIdString", "factory", "prdWo", "prdDateString",
                    "stockInDateString", "poNo","soNo"  ,"soItem","soType","sellFlag","inspNo",
                    "mfgPlant","mfgLine"
            };
            excel = HttpExcel.importExcel(inputStream, ImportGoodsTempRequest.class, properties);
        } catch (Exception e) {
            // 模板错误，请确认
            e.printStackTrace();
            Shift.fatal(StatusCode.IMPORT_DATA_ERROR);
        }
        if (excel == null || excel.size() == 0) {
            // 该模板数据为空
            Shift.fatal(StatusCode.IMPORT_DATA_NULL);
        }
        // 失败、成功条数
        int fail = excel.size(), sucess = 0;
        // 失败记录集合
        List<ImportGoodsTempErrorResponse> errors = new ArrayList<>();

        for (ImportGoodsTempRequest dto : excel) {
            boolean flag = true;

            //校验时间格式
            if (flag){
                if (dto.getPrdDateString()!=null){
                    Date prdDate = this.stringChangeDate(dto.getPrdDateString());
                    if (prdDate==null){
                        ImportGoodsTempErrorResponse error = new ImportGoodsTempErrorResponse();
                        BeanUtil.copyNonNull(dto, error);
                        StringBuilder errorDec = new StringBuilder("【第");
                        errorDec.append(dto.getRow()).append("行】生产日期格式错误,如2021年2月5日");
                        error.setRowMessage(errorDec.toString());
                        errors.add(error);
                        flag = false;
                    }else {
                        dto.setPrdDate(prdDate);
                    }
                }
            }
            if (flag){
                if (dto.getStockInDateString()!=null){
                    Date stockInDate = this.stringChangeDate(dto.getStockInDateString());
                    if (stockInDate==null){
                        ImportGoodsTempErrorResponse error = new ImportGoodsTempErrorResponse();
                        BeanUtil.copyNonNull(dto, error);
                        StringBuilder errorDec = new StringBuilder("【第");
                        errorDec.append(dto.getRow()).append("行】入库日期格式错误，如2021/2/5");
                        error.setRowMessage(errorDec.toString());
                        errors.add(error);
                        flag = false;
                    }else {
                        dto.setStockInDate(stockInDate);
                    }
                }
            }

            //校验字段不能为空
            for (String message : ValidatorUtil.validatorMessages(dto)) {
                ImportGoodsTempErrorResponse error = new ImportGoodsTempErrorResponse();
                BeanUtil.copyNonNull(dto, error);


                error.setRowMessage(this.checkNotNull(dto));

                errors.add(error);
                flag = false;
                break;
            }

            Boolean mid=false;

            //0.校验内外销标识合法性
            if (flag){
                for (int i = 0; i < sellFlags.length; i++) {
                    if (sellFlags[i].equals(dto.getSellFlag())){
                        mid=true;
                        break;
                    }
                }
                if(!mid){
                    ImportGoodsTempErrorResponse error = new ImportGoodsTempErrorResponse();
                    BeanUtil.copyNonNull(dto, error);
                    StringBuilder errorDec = new StringBuilder("【第");
                    errorDec.append(dto.getRow()).append("行】内外销标识必须为外销OEM/外销品牌/内销");
                    error.setRowMessage(errorDec.toString());
                    errors.add(error);
                    flag = false;
                }
            }
            mid=false;

            //1设置内外销标识
            if (flag){
                if ("外销OEM".equals(dto.getSellFlag())){
                    dto.setSellFlag("10");
                }else if ("外销品牌".equals(dto.getSellFlag())){
                    dto.setSellFlag("20");
                }else if ("内销".equals(dto.getSellFlag())){
                    dto.setSellFlag("30");
                }
            }

            //2:校验goodsSn是否存在
            if (flag){
                List<String> goodsSn = goodsTempMapper.selectSnByGoodsSn(dto.getGoodsSn());
                if (goodsSn!=null&&goodsSn.size()>0){
                    ImportGoodsTempErrorResponse error = new ImportGoodsTempErrorResponse();
                    BeanUtil.copyNonNull(dto, error);
                    StringBuilder errorDec = new StringBuilder("【第");
                    errorDec.append(dto.getRow()).append("行】整机SN已经存在");
                    error.setRowMessage(errorDec.toString());
                    errors.add(error);
                    flag = false;
                }
            }


            //3.检验销售订单类型合法性
            if (flag){

                for (int i = 0; i < soTypes.length; i++) {
                    if (soTypes[i].equals(dto.getSoType())){
                        mid=true;
                        break;
                    }
                }
                if (!mid){
                    ImportGoodsTempErrorResponse error = new ImportGoodsTempErrorResponse();
                    BeanUtil.copyNonNull(dto, error);
                    StringBuilder errorDec = new StringBuilder("【第");
                    errorDec.append(dto.getRow()).append("行】销售订单类型必须为易损件订单/整机订单/样机订单/散件订单");
                    error.setRowMessage(errorDec.toString());
                    errors.add(error);
                    flag = false;
                }
            }

            mid=false;

            //4.校验物料代码存在性
            if (flag){
                Integer skuId = skuMapper.selectSkuIdByCode(dto.getSkuIdString());
                if (skuId==null){
                    ImportGoodsTempErrorResponse error = new ImportGoodsTempErrorResponse();
                    BeanUtil.copyNonNull(dto, error);
                    StringBuilder errorDec = new StringBuilder("【第");
                    errorDec.append(dto.getRow()).append("行】整机物料代码不存在");
                    error.setRowMessage(errorDec.toString());
                    errors.add(error);
                    flag = false;
                }else {
                    dto.setSkuId(new BigDecimal(skuId));
                }
            }
            //5.校验组织合法性
            if (flag){
                if (!(dto.getFactory().equals("5500")||dto.getFactory().equals("5520"))){
                    ImportGoodsTempErrorResponse error = new ImportGoodsTempErrorResponse();
                    BeanUtil.copyNonNull(dto, error);
                    StringBuilder errorDec = new StringBuilder("【第");
                    errorDec.append(dto.getRow()).append("行】工厂代码须为5500/5520");
                    error.setRowMessage(errorDec.toString());
                    errors.add(error);
                    flag = false;
                }
            }
            //设置默认货主
            DataItemDetailDTO dataItem=new DataItemDetailDTO();
            List<DataItemDetailDTO> dataItemDetailByCode = dataItemDetailApi.getDataItemDetailByCode(DEFAULT_OWNER);
            for (DataItemDetailDTO dataItemDetailDTO : dataItemDetailByCode) {
                if (DEFAULT_OWNER.equals(dataItemDetailDTO.getItemCode())){
                    dataItem=dataItemDetailDTO;
                }
            }
           //放生产时记得怼上这段代码，测试先放行
            if (flag){
                if (dataItem == null || dataItem.getItemValue() == null ){
                    ImportGoodsTempErrorResponse error = new ImportGoodsTempErrorResponse();
                    BeanUtil.copyNonNull(dto, error);
                    StringBuilder errorDec = new StringBuilder("【第");
                    errorDec.append(dto.getRow()).append("行】没有默认货主，请配置数据字典!");
                    error.setRowMessage(errorDec.toString());
                    errors.add(error);
                    flag = false;
                }
            }

            //设置日期等信息并新增
            if (flag){
                dto.setCreateTime(new Date());
                dto.setCreateUser(loginName);

                int ownerId = (dataItem == null || dataItem.getItemValue() == null ? 0 : Integer.parseInt(dataItem.getItemValue()));
                dto.setOwner(ownerId);

                goodsTempMapper.insertExcel(dto);
                ImportGoodsTempErrorResponse success = new ImportGoodsTempErrorResponse();
                BeanUtil.copyNonNull(dto, success);
                errors.add(success);
                --fail;
                ++sucess;
            }

        }
        ImportGoodsTempResponse response = new ImportGoodsTempResponse();
        response.setFailureCount(fail);
        response.setSucceessCount(sucess);
        response.setItems(errors);
        return response;
    }

    public PagerInfo<List<GoodsTempResponse>> searchGoodsTemp(
            SearchGoodsTempRequest search, Pager<?> pager) {
        //去除查询字段的空格
        this.filterSpace(search);
        Page<GoodsTempResponse> page = PageHelper.offsetPage(pager.getSkipCount(), pager.getMaxResultCount());
        List<GoodsTempResponse> datas = goodsTempMapper.selectAll(search);
        //设置枚举值
        for (GoodsTempResponse data : datas) {
            if (data.getInvAttr()!=null){
                if (data.getInvAttr().equals("K")){
                    data.setReturnInvAttr("寄售");
                }else if (data.getInvAttr().equals("E")){
                    data.setReturnInvAttr("销售订单");
                }
                else if (data.getInvAttr().equals("S")){
                    data.setReturnInvAttr("标准");
                }
            }

            if (data.getIsHold()!=null){
                data.setReturnIsHold(WorkDivisionIsEnabledEnum.getEnumByCode(data.getIsHold()).enumName);
            }

            if (data.getIsAccept()!=null){
                data.setReturnIsAccept(WorkDivisionIsEnabledEnum.getEnumByCode(data.getIsAccept()).enumName);
            }

            if (data.getIsOldPack()!=null){
                data.setReturnIsOldPack(WorkDivisionIsEnabledEnum.getEnumByCode(data.getIsOldPack()).enumName);
            }

            data.setReturnStatus(GoodsStatusEnum.getEnumByCode(data.getStatus()).enumName);

        }

        PagerInfo<List<GoodsTempResponse>> pagerInfo = new PagerInfo<>();
        pagerInfo.setTotalCount(page.getTotal());
        pagerInfo.setItems(datas);
        return pagerInfo;
    }

    //去除空格
    private void filterSpace(SearchGoodsTempRequest search){
        if (search.getFilter()!=null){
            search.setFilter(search.getFilter().replace(" ",""));
        }
        if (search.getGoodsSn()!=null){
            search.setGoodsSn(search.getGoodsSn().replace(" ",""));
        }
        if (search.getPrdWo()!=null){
            search.setPrdWo(search.getPrdWo().replace(" ",""));
        }
        if (search.getPoNo()!=null){
            search.setPoNo(search.getPoNo().replace(" ",""));
        }
        if (search.getSoNo()!=null){
            search.setSoNo(search.getSoNo().replace(" ",""));
        }
        if (search.getSoItem()!=null){
            search.setSoItem(search.getSoItem().replace(" ",""));
        }
        if (search.getUdf5()!=null){
            search.setUdf5(search.getUdf5().replace(" ",""));
        }
    }

}
